package chapter05

object Test05_Lambda {
  def main(args: Array[String]): Unit = {

    //1、Lambda 表达式 如何调用
    val fun = (name: String) => {
      println(name)
    }

    fun("atguigu")

    println("============================================")

    //把函数当作参数传入
    def f(func: String => Unit): Unit = {
      func("atguigu")
    }

    f(fun)
    f((name: String) => {
      println(name)
    })

    println("============================================")


    //匿名函数的简化原则
    // (1) 参数类型可以省略，会根据形参进行自动推导
    f((name: String) => {
      println(name)

    })
    println("============================================")
    //2、类型省略之后，发现只有一个参数、则圆括号可以省略、其他情况、没有参数和参数超过1的永远不能省略圆括号
    f(name => {
      println(name)
    })

    println("============================================")
    //3、匿名函数如果只有一行、则大括号可以省略
    f(name => println(name))

    println("========================4====================")
    //4、如果参数只出现一次、则参数省略且后面参数可以用_代替
    f(println(_))

    println("========================5====================")
    //5 如果可以推断出，当前传入的println是一个函数体，而不是调用语句、可以直接省略下划线
    f(println)


    //实际示例定义一个 二次运算符 只操作1和2两个数，但是具体运算通过参数传入
    def dualFunctionOneAndTwo(fun: (Int, Int) => Int) = {
      fun(1, 2)

    }

    //匿名函数简化
    val add = (a: Int, b: Int) => a + b
    val minus = (a: Int, b: Int) => a - b

    println(dualFunctionOneAndTwo(add))
    println(dualFunctionOneAndTwo(minus))
    println("===================================")

    println(dualFunctionOneAndTwo((a, b) => a + b))
    println(dualFunctionOneAndTwo(_ + _))
    println(dualFunctionOneAndTwo(_ - _))
    println("===================================")
    println(dualFunctionOneAndTwo((a, b) => b - a))
    println(dualFunctionOneAndTwo(-_ + _))


  }


}
